package com.xrh.xdemo.service.service;


import java.util.Collection;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xrh.core.bean.CommonPage;
import com.xrh.core.bean.CommonResult;
import com.xrh.core.exceptions.BusinessException;
import com.xrh.xdemo.api.dto.entity.SysUserDTO;
import com.xrh.xdemo.api.dto.entity.UserVsRoleDTO;
import com.xrh.xdemo.api.request.addRequest.UserVsRoleAddRequest;
import com.xrh.xdemo.api.request.queryRequest.UserVsRoleQueryRequest;
import com.xrh.xdemo.api.request.updateRequest.UserVsRoleUpdateRequest;
import com.xrh.xdemo.service.entity.UserVsRoleEntity;
import com.xrh.xdemo.service.mapper.UserVsRoleMapper;
import com.xrh.xdemo.service.utils.LoginUtils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;

@Service
public class UserVsRoleService {

	@Resource
	UserVsRoleMapper userVsRoleMapper;
	
	
	/**
	 * @function 获取用户拥有的角色id
	 * @author 肖荣辉
	 * @date 2023年12月8日
	*/
	public Set<Long> getUserRoleIds(){
		
		SysUserDTO user = LoginUtils.getUser();
		
		return getRoleIdsByUserId(user.getId());
	}
	
	/**
	 * @function 获取用户拥有的角色id
	 * @author 肖荣辉
	 * @date 2023年12月8日
	*/
	public Set<Long> getRoleIdsByUserId(Long userId){
		
		LambdaQueryWrapper<UserVsRoleEntity> queryWrapper = new LambdaQueryWrapper<UserVsRoleEntity>();
		
		queryWrapper.eq(UserVsRoleEntity::getSysUserId, userId);
		
		return CollStreamUtil.toSet(userVsRoleMapper.selectList(queryWrapper), UserVsRoleEntity::getSysRoleId);
		
	}
	
	/**
	 * @function 获取角色绑定的所有用户ids
	 * @author 肖荣辉
	 * @date 2023年12月8日
	*/
	public Set<Long> getUserIdsByRoleId(Long roleId){
		
		LambdaQueryWrapper<UserVsRoleEntity> queryWrapper = new LambdaQueryWrapper<UserVsRoleEntity>();
		
		queryWrapper.eq(UserVsRoleEntity::getSysRoleId, roleId);
		
		return CollStreamUtil.toSet(userVsRoleMapper.selectList(queryWrapper), UserVsRoleEntity::getSysUserId);
		
	}
	
	/**
	 * @function 新增UserVsRole
	 * @param userVsRoleAddRequest
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	public Long addUserVsRole(UserVsRoleAddRequest userVsRoleAddRequest) {
		
		UserVsRoleEntity userVsRoleEntity = new UserVsRoleEntity();
		
		BeanUtil.copyProperties(userVsRoleAddRequest , userVsRoleEntity , CopyOptions.create().ignoreNullValue());
		
		userVsRoleMapper.insert(userVsRoleEntity);
		
		return userVsRoleEntity.getId();
	}

	/**
	 * @function 删除UserVsRole
	 * @param id
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	public void deleteUserVsRoleById(Long id) {
		
		if(id == null)
			throw new BusinessException("id不能为空");
			
		UserVsRoleEntity userVsRoleEntity = userVsRoleMapper.selectById(id);
		
		if(userVsRoleEntity == null)
			throw new BusinessException("id不合法");
		
		UpdateWrapper<UserVsRoleEntity> updateWrapper = new UpdateWrapper<>();
		updateWrapper.eq("id", id);
		
		//因为注解了@TableLogic , 自动会把删除标志位设置为1 
		userVsRoleMapper.delete(updateWrapper);
		
	}

	/**
	 * @function 修改UserVsRole
	 * @param userVsRoleUpdateRequest
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	public void updateUserVsRole(UserVsRoleUpdateRequest userVsRoleUpdateRequest) {
		
		if(userVsRoleUpdateRequest.getId() == null)
			throw new BusinessException("id不能为空");
		
		UserVsRoleEntity userVsRoleEntity = userVsRoleMapper.selectById(userVsRoleUpdateRequest.getId());
		
		if(userVsRoleEntity == null)
			throw new BusinessException("id不合法");
		
		BeanUtil.copyProperties(userVsRoleUpdateRequest , userVsRoleEntity , CopyOptions.create().ignoreNullValue());
		
		userVsRoleMapper.updateById(userVsRoleEntity);
		
	}

	/**
	 * @function 根据ID查询UserVsRole Entity
	 * @param id
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	public UserVsRoleEntity findUserVsRoleEntityById(Long id) {
		
		if(id == null)
			throw new BusinessException("id不能为空");
			
		UserVsRoleEntity userVsRoleEntity = userVsRoleMapper.selectById(id);
		
		return userVsRoleEntity;
	}
	
	/**
	 * @function 根据ID查询UserVsRole DTO
	 * @param id
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	public UserVsRoleDTO findUserVsRoleById(Long id) {
		
		if(id == null)
			throw new BusinessException("id不能为空");
	
		UserVsRoleEntity userVsRoleEntity = userVsRoleMapper.selectById(id);
		
		UserVsRoleDTO  userVsRoleDTO = BeanUtil.toBean(userVsRoleEntity , UserVsRoleDTO.class);
		
		return userVsRoleDTO;
	}

	/**
	 * @function 根据UserVsRoleQueryVo查询UserVsRole列表
	 * @param userVsRoleQueryRequest
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	public CommonResult<CommonPage<UserVsRoleDTO>> findUserVsRoleList(UserVsRoleQueryRequest userVsRoleQueryRequest) {
		
		Page<UserVsRoleEntity> page = userVsRoleQueryRequest.createPage();

		QueryWrapper<UserVsRoleEntity> queryWrapper = userVsRoleQueryRequest.createQuery();
		
		userVsRoleMapper.selectPage(page, queryWrapper);
		
		List<UserVsRoleDTO> dtoList = BeanUtil.copyToList(page.getRecords() , UserVsRoleDTO.class);
		
		return CommonResult.success(CommonPage.create(userVsRoleQueryRequest.getPageNum() , userVsRoleQueryRequest.getPageSize() , dtoList, page.getTotal()));
	}
	
	/**
	 * @function 查询指定角色和用户集合的记录信息
	 * @author 肖荣辉
	 * @date 2023年12月8日
	*/
	public List<UserVsRoleEntity> findEntityListByRoleIdAndUserIds(Long roleId, Collection<Long> userIds) {
		
		LambdaQueryWrapper<UserVsRoleEntity> queryWrapper = new LambdaQueryWrapper<UserVsRoleEntity>();
		
		queryWrapper.eq(UserVsRoleEntity::getSysRoleId, roleId);
		
		queryWrapper.in(UserVsRoleEntity::getSysUserId, userIds);
		
		return userVsRoleMapper.selectList(queryWrapper);
	}
	
	/**
	 * @function 角色解绑用户
	 * @author 肖荣辉
	 * @date 2023年12月8日
	*/
	@Transactional
	public void roleUnBindUsers(Long roleId, Collection<Long> userIds) {
		
		List<UserVsRoleEntity> list = findEntityListByRoleIdAndUserIds(roleId , userIds);
		
		if(CollUtil.isEmpty(list))
			return;
		
		for(UserVsRoleEntity item : list) {
			userVsRoleMapper.deleteById(item.getId());
		}
		
	}
	
	/**
	 * @function 角色绑定用户
	 * @author 肖荣辉
	 * @date 2023年12月8日
	*/
	@Transactional
	public void roleBindUsers(Long roleId, Collection<Long> userIds) {
		
		List<UserVsRoleEntity> list = findEntityListByRoleIdAndUserIds(roleId , userIds);
		
		//已经绑定的用户
		Set<Long> existUserIds = CollStreamUtil.toSet(list, UserVsRoleEntity::getSysUserId);
		
		for(Long userId : userIds) {
			
			if(existUserIds.contains(userId)) continue;
			
			UserVsRoleEntity entity = new UserVsRoleEntity();
			
			entity.setSysUserId(userId);
			entity.setSysRoleId(roleId);
			
			userVsRoleMapper.insert(entity);
			
		}
		
	}
	
	
	/**
	 * @function 重置用户和角色的绑定关系
	 * @param roleIds
	 * @author 肖荣辉
	 * @date 2023年12月8日
	*/
	public void resetUserBindRoles(Long userId , Collection<Long> roleIds) {
		
		//先删除 , 后新增
		userVsRoleMapper.delete(new LambdaQueryWrapper<UserVsRoleEntity>().eq(UserVsRoleEntity::getSysUserId, userId));
		
		if(CollUtil.isEmpty(roleIds)) return;
		
		for(Long roleId : roleIds) {
			
			UserVsRoleEntity entity = new UserVsRoleEntity();
			
			entity.setSysUserId(userId);
			entity.setSysRoleId(roleId);
			
			userVsRoleMapper.insert(entity);
			
		}
		
	}
	
}
